iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0
Software Development

30天收斂後端開發心法系列 第 27

30天收斂後端開發心法 - (27) Dockerfile

  • 分享至 

  • xImage
  •  

Dockerfile 說明與多階段建構介紹

當我們在開發專案時,往往會發現現成的 image 無法完全符合我們的需求。這時就可以透過自訂的 Dockerfile 來擴充、修改這些 image,進而產出屬於我們的專案容器環境。

Dockerfile 的設計目的

就是把專案所需的環境寫成一份可以被版控、可重現、可移植的檔案,這也是 Docker 為什麼能達成「環境一致」的核心原因。

其實說穿了,Dockerfile 就是照著 Docker 能理解的格式語法,一行行地指定「這個 image 應該具備什麼樣的環境與工具」。

實際範例解析

第一階段:定義基礎 image 與打包環境

FROM php:8.3-fpm-alpine3.20 AS app
這行代表我們的自訂 image 是以官方 PHP 8.3 的 Alpine Linux 版本為基礎。使用 Alpine 可以減少 image 的大小,適合部署環境。
AS app 是給這個階段起個名字,方便之後引用。

FROM app AS build
這是 Docker 的多階段建構(multi-stage build)技巧。這裡表示我們要「以剛剛命名為 app 的 image」為基礎,建立一個名為 build 的階段。

接下來會在這個階段中安裝 PHP 擴充套件與 composer 套件。

設定工作目錄

WORKDIR /www
設定 container 內的預設工作目錄為 /www,後續的命令會以此為根目錄執行。

安裝建構工具與 PHP 擴充套件

RUN set -eux; \
    apk add --no-cache \
    autoconf \
    ca-certificates \
    curl \
    gcc \
    g++ \
    make \
    libpng-dev \
    zlib-dev \
    libzip-dev \
    linux-headers \
    gmp-dev;

這段透過 Alpine 的套件管理工具 apk 安裝了建構 PHP 擴充套件所需的工具與開發函式庫(例如:libzip-dev 是為了安裝 PHP 的 zip 擴充)。

RUN set -eux; \
    docker-php-ext-install -j$(nproc) \
    gd \
    zip \
    pdo_mysql \
    bcmath \
    gmp ;

這段是使用 PHP 官方 image 內建的指令 docker-php-ext-install,用來安裝常見的 PHP 擴充套件,這些模組是 Laravel 等框架常用的。

安裝 Composer 依賴

WORKDIR /tmp/composer
COPY --from=composer:2.2 /usr/bin/composer /usr/local/bin/composer
COPY composer.* /tmp/composer/

這裡先切換到 /tmp/composer 目錄(在 container 中),接著:

把官方 composer image 中的執行檔拷貝進來

並把本機的 composer.json 與 composer.lock 複製進 container,準備進行依賴安裝

RUN set -eux; \
    composer install --no-autoloader --no-ansi --no-progress --no-dev;

這是執行 composer install 來安裝生產環境所需的套件(不含 dev 套件),而且為了加速建構過程,略過 autoloader 的生成與格式化輸出。

第二階段:組合成最終 production image

FROM app

這是新的 build 階段,會使用之前定義過的 app 作為基礎(也就是乾淨、尚未做過任何安裝的 PHP + Alpine 環境)。

接著將上一個 build 階段建好的檔案與設定複製進來:

COPY --from=build /usr/local/lib/php/extensions /usr/local/lib/php/extensions
COPY --from=build /usr/local/etc/php /usr/local/etc/php
COPY --from=build /usr/lib /usr/lib
COPY --from=composer:2.2 /usr/bin/composer /usr/local/bin/composer

這樣就不需要在這個 image 再次安裝任何東西,節省空間與建構時間。

複製專案原始碼與依賴

WORKDIR /www
COPY --from=build /tmp/composer/vendor /www/vendor
COPY . .
COPY . . 是將本地所有專案檔案複製進 container
COPY --from=build 

則是將剛剛安裝好的 composer 套件複製進來,避免在 production image 中重複執行 install

最後優化 Composer 設定

RUN set -eux; \
    composer dump --optimize --no-ansi;

這會重新生成 optimized autoloader,讓 Laravel 在執行時效能更佳。

為什麼使用 Multi-stage build?

使用多階段建構(multi-stage build)的好處包括:

  • 減少最終 image 大小:只帶入必要檔案,不包含開發工具與建構工具。
  • 提高安全性:避免將不必要的程式或憑證留在 image 中。
  • 加速建構與 CI/CD:能分階段 cache,加快部署速度。

上一篇
30天收斂後端開發心法 - (26) Docker
下一篇
30天收斂後端開發心法 - (28) Docker Compose
系列文
30天收斂後端開發心法30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言